package uk.ac.manchester.tewpl.iceiface.client;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import uk.ac.manchester.tewpl.iceiface.client.curriculummap.Canvas;
import uk.ac.manchester.tewpl.iceiface.client.curriculummap.LayoutContainerMouse;
import uk.ac.manchester.tewpl.iceiface.client.curriculummap.Map;
import uk.ac.manchester.tewpl.iceiface.client.curriculummap.Uri;

import com.extjs.gxt.ui.client.Style;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.Style.Orientation;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.core.XTemplate;
import com.extjs.gxt.ui.client.data.BaseModelData;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ContainerEvent;
import com.extjs.gxt.ui.client.event.DomEvent;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.HtmlContainerEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.event.TabPanelEvent;
import com.extjs.gxt.ui.client.event.WindowEvent;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.util.Padding;
import com.extjs.gxt.ui.client.widget.ComponentHelper;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Html;
import com.extjs.gxt.ui.client.widget.HtmlContainer;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.Text;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.Radio;
import com.extjs.gxt.ui.client.widget.form.RadioGroup;
import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridGroupRenderer;
import com.extjs.gxt.ui.client.widget.grid.GroupColumnData;
import com.extjs.gxt.ui.client.widget.grid.GroupingView;
import com.extjs.gxt.ui.client.widget.grid.RowExpander;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.MarginData;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.layout.TableData;
import com.extjs.gxt.ui.client.widget.layout.VBoxLayout;
import com.extjs.gxt.ui.client.widget.layout.VBoxLayout.VBoxLayoutAlign;
import com.extjs.gxt.ui.client.widget.tips.ToolTipConfig;
import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseEvent;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.widgetideas.graphics.client.Color;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;;

public class CurriculumMapWindow extends Window {
	
	private Map map;
	private LayoutContainer mapContainer;
	
	private GroupingStore<BaseModelData> dataStore;

	public CurriculumMapWindow() {
		// Configure window
		setSize(760,660);
		setMinimizable(true);
		setMaximizable(true);
		setHeading("Curriculum Map");
		setMinWidth(760);
		setMinHeight(520);
		
		// Set up window layout
		setLayout(new BorderLayout());
		
		// North, contains map + filter panel
		LayoutContainer northPanel = new LayoutContainer();
		northPanel.setLayout(new BorderLayout());
		
		BorderLayoutData northPanelData = new BorderLayoutData(LayoutRegion.NORTH, 460);
		northPanelData.setMargins(new Margins(4,4,0,4));
		northPanelData.setSplit(true);
		
		// Results Panel
		ContentPanel resultsPanel = new ContentPanel();
		resultsPanel.setHeaderVisible(false);
		
		BorderLayoutData resultsPanelData = new BorderLayoutData(LayoutRegion.CENTER);
		resultsPanelData.setMargins(new Margins(4));
		
		// Results panel toolbar
		ToolBar resultsToolBar = new ToolBar();		
		
		// Report button
		Button reportButton = new Button("Create Report", new SelectionListener<ButtonEvent>() {
			@Override
			public void componentSelected(ButtonEvent ce) {
				Window w = new Window();
				w.setSize(200, 200);
				w.add(new Text("Report window"));
				w.show();
			}
		});
		
		resultsToolBar.add(reportButton);
		
		// Radio boxes
		Radio allView = new Radio();
		allView.setBoxLabel("All");
		allView.setValue(true);
		
		Radio orphanView = new Radio();
		orphanView.setBoxLabel("Orphans");
		orphanView.setValue(false);
		
		RadioGroup viewSelection = new RadioGroup();
		viewSelection.add(allView);
		viewSelection.add(orphanView);
		
		resultsToolBar.add(new FillToolItem());
		resultsToolBar.add(new LabelToolItem("Show:"));
		resultsToolBar.add(viewSelection);
		
		resultsPanel.setTopComponent(resultsToolBar);
		
		// Map panel
		mapContainer = new LayoutContainer();
		//mapContainer.setHeaderVisible(false);
		mapContainer.setLayout(new FitLayout());
		
		BorderLayoutData mapContainerData = new BorderLayoutData(LayoutRegion.CENTER);
		mapContainerData.setMargins(new Margins(0,4,0,0));
		
		// Filters panel		
		final ContentPanel filterPanel = new ContentPanel();
		//filterPanel.setLayout(new RowLayout(Orientation.VERTICAL));
		filterPanel.setHeaderVisible(true);
		filterPanel.setHeading("Filters");
		filterPanel.setScrollMode(Scroll.AUTOY);
		
		// Fiters panel toolbar
		ToolBar filterToolBar = new ToolBar();
		filterPanel.setTopComponent(filterToolBar);
		filterToolBar.add(new LabelToolItem("Time Period:"));
		filterToolBar.add(new FillToolItem());
		
		// Time period combo box
		ComboBox<BaseModelData> timePeriodCombo = new ComboBox<BaseModelData>();
		ListStore<BaseModelData> timePeriodStore = new ListStore<BaseModelData>();
		
		// Test data
		List<BaseModelData> data = new ArrayList<BaseModelData>();
		for (int i=0; i<4; i++) {
			java.util.Map<String, Object> props = new HashMap<String, Object>();
			props.put("label", "Year " + i);
			data.add(new BaseModelData(props));
		}
		
		timePeriodCombo.setStore(timePeriodStore);
		timePeriodCombo.setDisplayField("label");
		timePeriodStore.add(data);
		timePeriodCombo.setAllowBlank(false);
		filterToolBar.add(timePeriodCombo);
		
		BorderLayoutData filterPanelData = new BorderLayoutData(LayoutRegion.EAST, 270);
		filterPanelData.setSplit(true);
		
		// Results tab
		//TabItem resultsTab = new TabItem("Results");
		//centerTabPanel.add(resultsTab);
		
		// Report tab
		//TabItem reportTab = new TabItem("Report");
		//centerTabPanel.add(reportTab);

		// Add panels
		northPanel.add(mapContainer, mapContainerData);
		northPanel.add(filterPanel, filterPanelData);
		
		add(northPanel, northPanelData);
		add(resultsPanel, resultsPanelData);
		//add(centerTabPanel, centerPanelData);
		
		// Create and add CuriculumMap Widget
		/*map = new Map(this);
		filterPanel.add(map.getDetailContainer());
		mapContainer.add(map);*/
		
		/*
		 * Resize/Move Listeners
		 */
		
		// Add window resize/move listener and propagate to CurriculumMap
		addListener(Events.Resize, new Listener<WindowEvent>() {
			public void handleEvent(WindowEvent event) {
				redrawCurriculumMap();
			}
		});
		addListener(Events.Move, new Listener<WindowEvent>() {
			public void handleEvent(WindowEvent event) {
				redrawCurriculumMap();
			}
		});
				
		/*
		 * GRID code
		 */
		
		//tabPanel.setSelection(resultsTab);
		
		// Test data
		/*List<BaseModelData> data = new ArrayList<BaseModelData>();
		for (int i=0; i<30; i++) {
			java.util.Map<String, Object> props = new HashMap<String, Object>();
			props.put("label", "result1");
			if (i<5)
				props.put("terminal", "T1");
			else if (i < 10)
				props.put("terminal", "T2");
			else if (i < 15)
				props.put("terminal", "T3");
			else if (i < 20)
				props.put("terminal", "T4");
			else if (i < 25)
				props.put("terminal", "T5");
			else 
				props.put("airport", "T6");
			data.add(new BaseModelData(props));
		}*/
		
		// Set up row expander
		RowExpander expander = new RowExpander();
		expander.setTemplate(XTemplate.create("<p><b>Properties<b>:{props}"));
		
		// Set up columns
		ColumnConfig column = new ColumnConfig("label", "Label", 200);
		ColumnConfig column2 = new ColumnConfig("description", "Description", 300);
		ColumnConfig column3 = new ColumnConfig("terminal", "Terminal", 200);
		
		// Create column collection
		List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
		configs.add(expander);
		configs.add(column);
		configs.add(column2);
		configs.add(column3);
		
		// Set column model
		final ColumnModel cm = new ColumnModel(configs);
		
		// Set store model
		dataStore = new GroupingStore<BaseModelData>();
		dataStore.groupBy("terminal");
		
		// GroupingView
		GroupingView view = new GroupingView();
		view.setForceFit(true); // Try and prevent horizontal scrolling
		view.setStartCollapsed(false);
		view.setShowGroupedColumn(false);
		
		// Add group count
		view.setGroupRenderer(new GridGroupRenderer() {
			@Override
			public String render(GroupColumnData data) {
				String str;
				
				if (data.group == "")
					str =  "At Airport ";
				else
					str = "At terminal: " + data.group;
				
				str += " (" + data.models.size() + " results)";
				return str;
			}
		});
		
		Grid<BaseModelData> grid = new Grid<BaseModelData>(dataStore, cm);
		//grid.setHideHeaders(true);
		grid.setView(view);
		grid.addPlugin(expander); 
		//resultsTab.setLayout(new FitLayout());
		//resultsTab.add(grid);
		resultsPanel.setLayout(new FitLayout());
		//resultsPanel.add(grid);
		
		//dataStore.add(data);		

	} // public CreateCurriculumMap()
	
	public void setData(List<java.util.Map<String, Object>> maps) {
		dataStore.removeAll();
		
		// Migrate map to data store
		List<BaseModelData> data = new ArrayList<BaseModelData>();
		
		for (java.util.Map<String, Object> map : maps) {
			data.add(new BaseModelData(map));
		}
		
		dataStore.add(data);
	}
	
	public void clearData() {
		dataStore.removeAll();
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.extjs.gxt.ui.client.widget.Window#show()
	 */
	@Override
	public void show() {
		super.show();
		redrawCurriculumMap();		
	}
	
	/*
	 * Helper to instruct the map to be re-drawn to the desired size
	 * upon resizing or moving the window 
	 */
	private void redrawCurriculumMap() {		
		if (map != null) {
			map.draw(mapContainer.getWidth(), mapContainer.getHeight());
		}
	}
	
	public void setCursor(String cursor) {
		setStyleAttribute("cursor", cursor);
	}

}
